package com.mogician.rabbitmq_demo.service;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mogician.rabbitmq_demo.bean.MyMessage;
import com.mogician.rabbitmq_demo.util.ConnectionUtil;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

import java.io.IOException;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

public class MQSubscribeService
{
    // 创建内部消息队列，供消费者获取消息用
    private ConnectionFactory factory;
    private Connection connection;

    public MQSubscribeService(Handler handler, final String exchangeName, final String routingKey)
    {
        factory = ConnectionUtil.setUpConnectionFactory();
        subscribe(handler, exchangeName, routingKey);
    }

    private void subscribe(final Handler handler, final String exchangeName, final String routingKey)
    {
        Thread subscribeThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 需要再次初始化数据的时候就关闭上一个连接
                    if(connection != null){
                        connection.close();
                    }
                    // 创建新的连接
                    connection = factory.newConnection();
                    // 创建通道
                    Channel channel = connection.createChannel();
                    // 处理完一个消息，再接收下一个消息
                    channel.basicQos(1);
//                    // 随机命名一个队列名称
//                    String queueName = System.currentTimeMillis() + "queueNameCar";
                    // 声明交换机类型
                    AMQP.Queue.DeclareOk q = channel.queueDeclare();
                    //将队列绑定到消息交换机exchange上
                    channel.queueBind(q.getQueue(), exchangeName, routingKey);

//                    channel.exchangeDeclare(queueName, "direct", true);
//                    // 声明队列（持久的、非独占的、连接断开后队列会自动删除）
//                    AMQP.Queue.DeclareOk q = channel.queueDeclare(queueName, true, false, true, null);// 声明共享队列
//                    // 根据路由键将队列绑定到交换机上（需要知道交换机名称和路由键名称）
//                    channel.queueBind(q.getQueue(), queueName, routingKey);
                    // 创建消费者获取rabbitMQ上的消息。每当获取到一条消息后，就会回调handleDelivery（）方法，该方法可以获取到消息数据并进行相应处理
                    Consumer consumer = new DefaultConsumer(channel){
                        @Override
                        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException
                        {
                            super.handleDelivery(consumerTag, envelope, properties, body);

//                            Log.d("", "[r] " + message);

                            //从message池中获取msg对象更高效
                            Message msg = handler.obtainMessage();
                            Bundle bundle = new Bundle();
                            bundle.putByteArray("msg", body);
                            msg.setData(bundle);
                            // 发消息通知UI更新
                            handler.sendMessage(msg);
                        }
                    };
                    channel.basicConsume(q.getQueue(), true, consumer);

                } catch (Exception e){
                    e.printStackTrace();
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        });
        subscribeThread.start();// 开启线程获取RabbitMQ推送消息
    }
}
